using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class DynamicObject : MonoBehaviour
{
    public SpineTouchConfigSO configSo;
    
    public List<FieldDefinition> definitions = new();

    private FieldContainer _fields;

    public void Initialize()
    {
        _fields = new FieldContainer();
        foreach (var definition in definitions)
        {
            DefineField(definition);
        }
    }

    private void OnDestroy()
    {
        _fields.Dispose();
    }

    public void Clear()
    {
        _fields.Clear();
    }

    // 添加字段定义
    public void DefineField(FieldDefinition definition)
    {
        _fields.AddField(definition.Name, IFieldData.CreateFieldData(definition.Type, definition.DefaultValue));
    }

    public void UndefineField(FieldDefinition definition)
    {
        _fields.RemoveField(definition.Name);
    }

    public IEnumerable<KeyValuePair<string,IFieldData>> GetFields()
    {
        return _fields.GetAllFields();
    }

    public int Count()
    {
        return _fields.FieldCount;
    }

    // 高频访问方法
    public bool GetBool(string name) => _fields.TryGetField(name, out bool value) ? value : false;
    public int GetInt(string name) => _fields.TryGetField(name, out int value) ? value : 0;
    public float GetFloat(string name) => _fields.TryGetField(name, out float value) ? value : 0f;

    public void SetBool(string name, bool value) => _fields.TrySetField(name, value);
    public void SetInt(string name, int value) => _fields.TrySetField(name, value);
    public void SetFloat(string name, float value) => _fields.TrySetField(name, value);

    public void SetValue(string name, IFieldData data)
    {
        var fileType = GetFieldType(name);
        if (fileType == FieldType.Bool && data is BoolFieldData boolFieldData)
        {
            SetBool(name, boolFieldData.Value);
        }
        else if (fileType == FieldType.Int && data is IntFieldData intFieldData)
        {
            SetInt(name, intFieldData.Value);
        }
        else if (fileType == FieldType.Float && data is FloatFieldData floatFieldData)
        {
            SetFloat(name, floatFieldData.Value);
        }
    }
    
    public bool Equals(string name, IFieldData value)
    {
        if (!_fields.ContainsField(name))
        {
            Debug.LogWarning($"{transform.name} does not contain a field {name} ");
            return false;
        }

        if (value is FieldData<bool> boolFieldData)
        {
            return boolFieldData.TryGetValue<bool>(out var boolval) && boolval == GetBool(name);
        }
        if (value is FieldData<int> intFieldData)
        {
            return intFieldData.TryGetValue<int>(out var intval) && intval == GetInt(name);
        }
        if (value is FieldData<float> floatFieldData)
        {
            return floatFieldData.TryGetValue<float>(out var floatval) && Mathf.Approximately(floatval, GetFloat(name));
        }
        
        return false;
    }

    public FieldType GetFieldType(string name)
    {
        var data = _fields.GetFieldData(name);
        if (data != null)
            return data.Type;
        return FieldType.Bool;
    }

    [ContextMenu("迁移数据到SO")]
    public void CopyData()
    {
        configSo.definitions = definitions;
        EditorUtility.SetDirty(configSo);
        AssetDatabase.SaveAssetIfDirty(configSo);
    }
}